package com.leff.cards;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.leff.cards.entity.Group;
import com.leff.cards.entity.User;

public class CloudMessenger implements Secrets {

	public static String sendInviteMessage(Group G, User U) {
		
		Message.Builder builder = new Message.Builder();
		builder.addData("type", "invite");
		builder.addData("title", G.getName());
		builder.addData("message", "You've been invited to join!");
		builder.addData("id", "" + G.getId());
		
		Message message = builder.build();
		return sendMessage(message, U);
	}
	
	public static String sendNewRoundMessage(Group G, User U) {
		Message message = groupMessage(G, U, "A new round has started - Do your worst!");
		return sendMessage(message, U);
	}
	
	public static String sendRoundWonMessage(Group G, User U) {
		Message message = groupMessage(G, U, "Your card was chosen! Keep up the terrible!");
		return sendMessage(message, U);
	}
	
	public static String sendVoteMessage(Group G, User U) {
		Message message = groupMessage(G, U, "It's time to vote for the most shameful response!");
		return sendMessage(message, U);
	}
	
	private static Message groupMessage(Group G, User U, String message) {
		
		Message.Builder builder = new Message.Builder();
		builder.addData("type", "group_update");
		builder.addData("title", G.getName());
		builder.addData("message", message);
		builder.addData("id", "" + G.getId());
		
		return builder.build();
	}
	
	private static String sendMessage(Message message, User U) {

		Logger log = Logger.getLogger("CloudMessenger");
		
		ArrayList<String> devices = U.getDeviceIds();
		if(devices.size() < 1) {
			return "No devices registered to user " + U.getDisplayName();
		}
		
		Sender sender = new Sender(GCM_API_KEY);
		String returnMessage = "";
		try {
			MulticastResult sendResult = sender.send(message, devices, 4);
			
			List<Result> results = sendResult.getResults();
			
			boolean dirty = false;
			for(int i = 0; i < results.size(); i++) {
				Result R = results.get(i);
				String oldId = devices.get(i);
				
				log.info("Result for device " + oldId + ":");
				
				if(R.getMessageId() != null) {
					String canonicalRegId = R.getCanonicalRegistrationId();
					
					if(canonicalRegId != null) {
						U.replaceDeviceId(oldId, canonicalRegId);
						dirty = true;
						returnMessage = "Replaced device id";
					} else {
						returnMessage = "Success";
					}
				}
				else if(R.getErrorCodeName() != null) {
					String error = R.getErrorCodeName();
					if(error.equals(Constants.ERROR_NOT_REGISTERED)) {
						U.removeDeviceId(oldId);
						dirty = true;
					}
					returnMessage = "Error: " + error;
				}
			}
			
			if(dirty) {
				StoreWrapper.store(U);
			}
			
			return returnMessage;
			
		} catch(IOException e) {
			return "IOException " + e;
		}
	}
}
